/*
@STI LICENSE
(C) 2006-2008 Universit�t Innsbruck.

This file is part of myOntology.

myOntologyis free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

myOntologyis distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with myOntology.  If not, see <http://www.gnu.org/licenses/>.

@STI LICENSE */
package org.myontology.specialpages.configs;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import org.myontology.controller.ResultSetHandler;
import org.myontology.controller.SesameSession;
import org.myontology.specialpages.EntryRow;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.vocabulary.RDF;
import org.openrdf.model.vocabulary.RDFS;
import org.openrdf.query.BindingSet;

public abstract class AbstractMostSpecialPage extends
		AbstractSerqlSpecialPageConfig {

	
	
	
	private SesameSession session;

	protected class FillList implements ResultSetHandler {
	
			public FillList(List<EntryRow> l,String u,Map<String, Integer> m) {
				list=l;
				uri=u;
				map=m;
			}
			
			Map<String, Integer> map;
			List<EntryRow> list;
			String uri;
			
			public void handleBindingSet(BindingSet set) {
				String type = set.getValue("t").stringValue();
				type=type.substring(type.lastIndexOf('#')+1);
				Value v = set.getValue("l");
				String label="NULL";
				if (v!=null)
				 label = v.stringValue();
				EntryRow row = new EntryRow(uri); 
				row.setType(type);
				row.setComment(set.getValue("c")==null?"-":set.getValue("c").stringValue());
				row.setLabel(label+" : "+map.get(uri)+" "+predicateLabel);
				list.add(row);
			}
			
		}

	protected static class BuildMap implements ResultSetHandler {
			Map<String,Integer> sortMap = new HashMap<String, Integer>();
			
	
			public void handleBindingSet(BindingSet set) {
				 String val = cutVersion(set.getValue("u").stringValue());
				 Integer i = sortMap.get(val);
					if (i==null) {
						sortMap.put(val, 1);
					}
					else
						sortMap.put(val, i.intValue()+1);
			}
			
			private String cutVersion(String fullString) {
				int lastPos = fullString.lastIndexOf("/v");
				if (lastPos>-1) {
					String end = fullString.substring(lastPos+2);
					try {
						Integer.parseInt(end);
						return fullString.substring(0,lastPos);
					}catch (Exception e){}
				}
				return fullString;
			}
		}

	protected String queryOverride=null;
	
	@Override
	protected List<EntryRow> select() {
		
		
		List<EntryRow> list = new ArrayList<EntryRow>();
		
		try {
				
			String query = "SELECT DISTINCT u FROM {u} <"+predicate+"> {}";
			if (queryOverride!=null)
				query = queryOverride;
			logger.info("special page query: "+query);
			BuildMap builder = new BuildMap();
			session.executeQuery(query,builder);
			
			TreeSet<String> sortedSet = new TreeSet<String>(new MapUsingComparator(builder.sortMap));
			sortedSet.addAll(builder.sortMap.keySet());
			for (Iterator<String> it = sortedSet.iterator();it.hasNext();) {
				String uri = it.next();
				query = "SELECT DISTINCT l,t,c FROM {<"+uri+">} <"+RDFS.LABEL+"> {l};<"+RDF.TYPE+"> {t};[<"+RDFS.COMMENT+"> {c}]";
				session.executeQuery(query,new FillList(list,uri,builder.sortMap));
			}
		}
		catch (Exception e) {
			logger.error(e);
		}
		return list;
	}

	protected static class MapUsingComparator implements Comparator<String> {
	
			Map<String,Integer> map;
			
			public MapUsingComparator(Map<String,Integer> sortMap) {
				map=sortMap;
			}
			
			public int compare(String o1, String o2) {
				try {
					return map.get(o2).intValue()-map.get(o1).intValue();
				}
				catch (Exception e) {
					
					return 0;
				}
			}
			
		}

	public AbstractMostSpecialPage(String label,URI p,String pLabel) {
		super(label);
		predicate=p;
		predicateLabel= pLabel;
	}

	private URI predicate;
	private String predicateLabel;

}
